using Microsoft.Extensions.Caching.Distributed;
using net_work.Common.Request;
using net_work.Common.Result;
using net_work.Common.Utils;
using net_work.IRepository.Sys;
using net_work.IService.ISystem;

namespace net_work.Service.System;

public class AuthService(IDistributedCache cache, IUserRepository userRepository) : IAuthService
{
    public async Task<LoginResult?> Authenticate(LoginRequest request)
    {
        // 验证用户名和密码
        var user = await userRepository.GetByAccountAsync(request.Account);
        if (user == null || user.UserPassword != request.Password)
        {
            return null;
        }

        var accessToken = JWTUtils.GenerateToken(user);
        var refreshToken = Guid.NewGuid().ToString();

        // 存储 Refresh Token 到 Redis，有效期7天
        await cache.SetStringAsync($"Login:Token:RefreshToken_{refreshToken}", user.Id.ToString(),
            new DistributedCacheEntryOptions
            {
                AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(7)
            });

        return new LoginResult
        {
            AccessToken = accessToken,
            RefreshToken = refreshToken
        };
    }

    public async Task<bool> ValidateCaptcha(string captchaId, string captcha)
    {
        // 验证验证码
        var storedCaptcha = await cache.GetStringAsync($"Login:Captcha:Captcha_{captchaId}");
        if (string.IsNullOrEmpty(storedCaptcha) ||
            !string.Equals(storedCaptcha, captcha, StringComparison.OrdinalIgnoreCase))
        {
            return false;
        }

        // 删除验证码（防止重复使用）
        await cache.RemoveAsync($"Login:Captcha:Captcha_{captchaId}");
        return true;
    }

    public async Task<LoginResult?> RefreshToken(string refreshToken)
    {
        // 验证 Refresh Token 是否正确
        var storedUserId = await cache.GetStringAsync($"Login:Token:RefreshToken_{refreshToken}");

        if (string.IsNullOrEmpty(storedUserId) || !long.TryParse(storedUserId, out var userId))
        {
            return null;
        }

        var user = await userRepository.GetByIdAsync(userId);
        if (user == null)
        {
            return null;
        }

        var newAccessToken = JWTUtils.GenerateToken(user);
        var newRefreshToken = Guid.NewGuid().ToString();

        // 更新 Redis 中的 Refresh Token
        await cache.RemoveAsync($"Login:Token:RefreshToken_{refreshToken}");
        await cache.SetStringAsync($"Login:Token:RefreshToken_{newRefreshToken}", user.Id.ToString(),
            new DistributedCacheEntryOptions
            {
                AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(7)
            });

        return new LoginResult
        {
            AccessToken = newAccessToken,
            RefreshToken = newRefreshToken
        };
    }

    public Task Logout(string refreshToken)
    {
        return cache.RemoveAsync($"Login:Token:RefreshToken_{refreshToken}");
    }
}